package com.etooling.framework.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 信息摘要类
 *
 * @author 李炽明
 * @version 0.9
 */

public class Digest {
    public Digest() {
    }

    public static final String MD5 = "MD5";
    public static final String SHA1 = "SHA-1";

    /**
     * <p>信息摘要</p>
     * 一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算，产生一个唯一指印。
     *
     * @param message   要进行采样摘要的字符串信息
     * @param algorithm 摘要算法,支持MD5和SHA-1
     * @return 信息摘要字节数组
     * @throws NoSuchAlgorithmException 指定的摘要算法有误
     */
    public static byte[] getMessageDigest(String message, String algorithm) throws
            NoSuchAlgorithmException {
        MessageDigest alg = MessageDigest.getInstance(algorithm);
        // 添加要进行计算摘要的信息
        alg.update(message.getBytes());
        // 计算出摘要
        return alg.digest();
    }

    /**
     * <p>信息摘要</p>
     * 一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算，产生一个唯一指印。
     *
     * @param message   要进行采样摘要的字节数组信息
     * @param algorithm 摘要算法,支持MD5和SHA-1
     * @return 信息摘要字节数组
     * @throws NoSuchAlgorithmException 指定的摘要算法有误
     */
    public static byte[] getMessageDigest(byte[] message, String algorithm) throws
            NoSuchAlgorithmException {
        MessageDigest alg = MessageDigest.getInstance(algorithm);
        // 添加要进行计算摘要的信息
        alg.update(message);
        // 计算出摘要
        return alg.digest();
    }

    /**
     * 按指定算法和摘要对信息进行校验
     *
     * @param message   原信息
     * @param algorithm 摘要算法
     * @param digest    要验证的摘要
     * @return 校验结果, true=校验正确,false=校验错误
     * @throws NoSuchAlgorithmException
     */
    public static boolean verifyMessageDigest(String message, String algorithm,
                                              byte[] digest) throws
            NoSuchAlgorithmException {
        MessageDigest alg = MessageDigest.getInstance(algorithm);
        alg.update(message.getBytes());
        return MessageDigest.isEqual(digest, alg.digest());
    }

    /**
     * 按指定算法和摘要对信息进行校验
     *
     * @param message   原字节数组信息
     * @param algorithm 摘要算法
     * @param digest    要验证的摘要
     * @return 校验结果, true=校验正确,false=校验错误
     * @throws NoSuchAlgorithmException
     */
    public static boolean verifyMessageDigest(byte[] message, String algorithm,
                                              byte[] digest) throws
            NoSuchAlgorithmException {
        MessageDigest alg = MessageDigest.getInstance(algorithm);
        alg.update(message);
        return MessageDigest.isEqual(digest, alg.digest());
    }


    /**
     * 将字节数组转换成字符串
     * 用作显示打印
     *
     * @param b 要转换的字节数组
     * @return 转换后的字符串, 以十六进制格式表示
     */
    public static String byte2hex(byte[] b) {
        if (b == null) {
            return "";
        }
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
            if (n < b.length - 1) {
                hs = hs + "-";
            }
        }
        return hs.toUpperCase();
    }

}